﻿using System;
using System.Collections.Generic;
using System.Text;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace LibParasInject
{
    static class ExtensionMethodBody
    {
        public static void injectBeforeAndFix(
            this MethodBody methodBody,
            Instruction targetBefore,
            params Instruction[] code
        )
        {
            var worker = methodBody.GetILProcessor();

            foreach (Instruction instrX in code)
            {
                worker.InsertBefore(targetBefore, instrX);
                FixLabels.updateReferences(targetBefore, instrX, methodBody);
            }
        }

        public static void injectBefore(
            this MethodBody methodBody,
            Instruction targetBefore,
            params Instruction[] code
        )
        {
            var worker = methodBody.GetILProcessor();

            foreach (Instruction instrX in code)
            {
                worker.InsertBefore(targetBefore, instrX);
            }
        }

        public static Instruction getStart(this MethodBody methodBody)
        {
            return methodBody.Instructions[0];
        }

        public static List<Instruction> getRets(this MethodBody methodBody)
        {
            return getInstrsByOpCode(methodBody, OpCodes.Ret);
        }

        public static List<Instruction> getThrows(this MethodBody methodBody)
        {
            return getInstrsByOpCode(methodBody, OpCodes.Throw);
        }

        static List<Instruction> getInstrsByOpCode(this MethodBody methodBody, OpCode op)
        {
            var instrs = new List<Instruction>();

            foreach (var instrX in methodBody.Instructions)
                if (op == instrX.OpCode)
                    instrs.Add(instrX);

            return instrs;
        }
    }
}

